//
//  StringExtension.swift
//  WalkNovel
//
//  Created by Kevin on 2023/7/4.
//

import UIKit
import CommonCrypto

// MARK: - 数字转换
extension String {
    /// 数量
    func wn_wan() -> String {
        guard self != "" else {
            return "0"
        }
        var s = self
        if Double(self)! >= 1000.0 {
            s = String(format: "%.1f k", Double(self)! / 1000.0)
        }
        if Double(self)! >= 1000000.0 {
            s = String(format: "%.1f m", Double(self)! / 1000000.0)
        }
        return s
    }
    
    /// 转Date
    func wn_toFormatDate(_ format: String = "yyyy/MM/dd")-> Date {
        guard self != "" else { return Date(timeIntervalSince1970: 0)}
        let dateFormat = DateFormatter()
        dateFormat.dateFormat = format
        dateFormat.timeZone = TimeZone.init(secondsFromGMT: 8)
        var date = Date()
        date = dateFormat.date(from: dateFormat.string(from: Date(timeIntervalSince1970: TimeInterval(Int(self)!))))!
        return date
    }
    
    /// 时间戳
    func wn_nowDate() -> String {
        return "\(Date().timeIntervalSince1970)".wn_toDate()
    }
    
    /// 随机数
    func wn_random(_ from: Int, _ to: Int) -> String {
        return String(format: "%ld", from + (Int(arc4random()) % (to - from + 1)))
    }
    
    /// 日期(秒)
    func wn_toDate(_ format: String = "yyyy/MM/dd HH:mm") -> String {
        let f = DateFormatter()
        f.dateFormat = format
        return f.string(from: Date(timeIntervalSince1970: TimeInterval(self)!))
    }
    
    /// 日期(毫秒)
    func wn_toDateMsec(_ format: String = "yyyy/MM/dd HH:mm") -> String {
        let f = DateFormatter()
        f.dateFormat = format
        return f.string(from: Date(timeIntervalSince1970: (TimeInterval(self)! / 1000)))
    }
    
    /// 时间戳转具体的间隔时间
    func wn_toJavaDetailDate(_ format: String = "yyyy/MM/dd HH:mm") -> String {
        let dateFormat = DateFormatter()
        dateFormat.dateFormat = format
        var date = Date()
        date = dateFormat.date(from: dateFormat.string(from: Date(timeIntervalSince1970: TimeInterval(wn_toInt(self)))))!
        let calendar = Calendar.current
        if calendar.isDateInToday(date) {
            /// 间隔秒数
            let timeInterval = Int(Date().timeIntervalSince(date))
            /// 如果小于60秒
            if timeInterval < 60 {
                dateFormat.dateFormat = "HH:mm"
                return "剛剛"
            }
            /// 小于1小时
            if timeInterval < 60 * 60 {
                dateFormat.dateFormat = "HH:mm"
                return "\(timeInterval / 60)分鐘前"
            }
            /// 小于1天，大于1小时
            dateFormat.dateFormat = "HH:mm"
            return "\(timeInterval / 3600)小時前"
        }
        /// 如果是昨天
        if calendar.isDateInYesterday(date) {
            dateFormat.dateFormat = "MM/dd HH:mm"
        }else {
            /// 如果不是昨天
            let year = calendar.component(.year, from: date)
            let thisYear = calendar.component(.year, from: Date())
            /// 如果是今年
            if year == thisYear {
                dateFormat.dateFormat = "MM/dd HH:mm"
            }else {
                dateFormat.dateFormat = "yyyy/MM/dd HH:mm"
            }
        }
        dateFormat.locale = Locale(identifier: "en")
        /// 返回需要的时间字符串
        return dateFormat.string(from: date)
    }
    
    func wn_toDuration() -> String {
        let d = wn_toInt(wn_toFloat(self))
        if d > 3600 {
            let h = d / 3600
            let m = d % 3600 / 60
            let s = d % 60
            return String(format: "%02d:%02d:%02d", h, m, s)
        }else {
            let m = d / 60
            let s = d % 60
            return String(format: "%02d:%02d", m, s)
        }
    }
    
    func wn_getTimeRange(date:Date, timeRange: String) -> (TimeInterval, TimeInterval) {
        func getCurrYear(date:Date) -> String {
            let dm = DateFormatter()
            dm.dateFormat = "yyyy."
            let currYear = dm.string(from: date)
            return currYear
        }
        func toTimeInterval(dateStr: String) -> TimeInterval? {
            let dm = DateFormatter()
            dm.dateFormat = "yyyy.MM.dd"
            let date = dm.date(from: dateStr)
            let interval = date?.timeIntervalSince1970
            return interval
        }
        let timeStrArr = timeRange.components(separatedBy: "-")
        let dateYear = getCurrYear(date: date)
        let startTimeStr = dateYear + timeStrArr.first!
        let endTimeStr = dateYear + timeStrArr.last!
        let startTime = toTimeInterval(dateStr: startTimeStr)!
        let endTime = toTimeInterval(dateStr: endTimeStr)!
        return (startTime, endTime)
    }
}

// MARK: - 计算宽度 / 高度
extension String {
    /// 改变字符串中数字的颜色和字体
    func wn_numberChange(_ color: UIColor, _ font: UIFont = .wn_font(name: .bold, size: 14), _ regx: String = "\\d+") -> NSMutableAttributedString {
        let attributeString = NSMutableAttributedString(string: self)
        do {
            // 数字正则表达式
            let regexExpression = try NSRegularExpression(pattern: regx, options: NSRegularExpression.Options())
            let result = regexExpression.matches(
                in: self,
                options: NSRegularExpression.MatchingOptions(),
                range: NSMakeRange(0, count)
            )
            for item in result {
                attributeString.setAttributes(
                    [.foregroundColor : color, .font: font],
                    range: item.range
                )
            }
        } catch {
        }
        return attributeString
    }
    
    /// 改变指定文本的颜色字体
    func wn_textChangeColor(_ string: String, _ colorStr1: String, _ colorStr2: String = "", _ color: UIColor, _ font: UIFont) -> NSMutableAttributedString {
        let attrstring = NSMutableAttributedString(string:string)
        let str = NSString(string: string)
        let theRange1 = str.range(of: colorStr1)
        let theRange2 = str.range(of: colorStr2)
        attrstring.addAttribute(NSAttributedString.Key.foregroundColor, value: color, range: theRange1)
        attrstring.addAttribute(NSAttributedString.Key.foregroundColor, value: color, range: theRange2)
        attrstring.addAttribute(NSAttributedString.Key.font, value: font, range: theRange1)
        attrstring.addAttribute(NSAttributedString.Key.font, value: font, range: theRange2)
        return attrstring
    }
    
    func repaceWhiteSapce() -> String {
        let regex = try? NSRegularExpression.init(pattern: "\\s{2,}", options: .caseInsensitive)
        var arr = (regex?.matches(in: self, options: .reportCompletion, range: NSRange.init(location: 0, length: self.count)))! as NSArray
        arr = arr.reverseObjectEnumerator().allObjects as NSArray
        var tepLevel = self as NSString
        for item in arr {
            tepLevel = tepLevel.replacingCharacters(in: (item as AnyObject).range, with: " ") as NSString
        }
        return tepLevel as String
    }
    
    /// 截取NSRange范围的子字符串
    func wn_subString(_ range: NSRange) -> String {
        let text = self as NSString
        let subStr = text.substring(with: range) as String
        return subStr
    }
    
    /// 获取子字符串的范围NSRange
    func wn_range(_ subString: String) -> NSRange {
        let text = self as NSString
        return text.range(of: subString)
    }
    
    func wn_findAllIndex(_ string: String) -> [NSRange] {
        var ranges:[NSRange] = []
        if string.elementsEqual(""){
            return ranges
        }
        let zero = self.startIndex
        let target = Array(string)
        let total = Array(self)
        let lenght = string.count
        var startPoint = 0
        while total.count >= startPoint + string.count{
            if total[startPoint] == target[0]{
                let startIndex = self.index(zero, offsetBy: startPoint)
                let endIndex = self.index(startIndex, offsetBy: lenght)
                let child = self[startIndex..<endIndex]
                if child.elementsEqual(string){
                    ranges.append(NSRange.init(location: startPoint, length: lenght))
                    startPoint += lenght
                }else{
                    startPoint += 1
                }
            }else{
                startPoint += 1
            }
        }
        return ranges
    }
    
    func wn_getImageFromURL(_ size: CGSize = .init(width: 20, height: 20)) -> UIImage {
        guard let url = URL(string: self) else { return UIImage() }
        guard let data = try? Data.init(contentsOf: url) else { return UIImage() }
        guard let image = UIImage.init(data: data) else { return UIImage() }
        return image.wn_resized(newSize: size)
    }
}

// MARK: - 加密方式
extension String {
    /// base64编码
    func wn_base64EncodedString() -> String {
        let data = self.data(using: String.Encoding.utf8)
        return data?.base64EncodedString(options: []) ?? ""
    }
    
    /// base64解码
    func wn_base64DecodedString() -> String {
        let data = Data.init(base64Encoded: self, options: [])
        return String(data: data ?? Data(), encoding: String.Encoding.utf8) ?? ""
    }
    
    /// 将原始的url编码为合法的url
    func urlEncoded() -> String {
        let encodeUrlString = self.addingPercentEncoding(withAllowedCharacters:.urlQueryAllowed)
        return encodeUrlString ?? ""
    }
    
    /// 将编码后的url转换回原始的url
    func urlDecoded() -> String {
        return self.removingPercentEncoding ?? ""
    }
    
    /// MD5加密
    func MD5String() -> String {
        let str = self.cString(using: .utf8)
        let strLen = CUnsignedInt(self.lengthOfBytes(using: .utf8))
        let digestLen = Int(CC_MD5_DIGEST_LENGTH)
        let result = UnsafeMutablePointer<UInt8>.allocate(capacity: digestLen)
        CC_MD5(str!, strLen, result)
        let hash = NSMutableString()
        for i in 0 ..< digestLen {
            hash.appendFormat("%02x", result[i])
        }
        free(result)
        return String(format: hash as String)
    }
    
    /// SHA256加密
    func SHA256String() -> String {
        let str = self.cString(using: .utf8)
        var digestLen = [UInt8](repeating: 0, count: Int(CC_SHA256_DIGEST_LENGTH))
        CC_SHA256(str, CC_LONG(str!.count - 1), &digestLen)
        return digestLen.reduce("") { $0 + String(format:"%02x", $1) }
    }
    
    /// SHA521
    func SHA521String() -> String {
        let data = self.data(using: .utf8) ?? Data()
        var digest = [UInt8](repeating: 0, count: Int(CC_SHA512_DIGEST_LENGTH))
        data.withUnsafeBytes {
            _ = CC_SHA512($0.baseAddress, CC_LONG(data.count), &digest)
        }
        return digest.map({ String(format: "%02hhx", $0) }).joined(separator: "")
    }
    
    /// 指定长度的随机字符串
    func randomAlphaNumericString(_ length: Int) -> String {
        var characters = Array(48...57).map {String(UnicodeScalar($0))}
        characters.append(contentsOf: Array(65...90).map {String(UnicodeScalar($0))})
        characters.append(contentsOf: Array(97...122).map {String(UnicodeScalar($0))})
        var randomString = String()
        for _ in 0..<length {
            let length = UInt32(characters.count)
            let randonIndex = Int(arc4random_uniform(length))
            randomString += characters[randonIndex]
        }
        return randomString
    }
}
